﻿using Knight.Interface;
using Knight.Models.Base;
using Knlght.Data;
using Knlght.Domain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Knight.Models.Services
{
    public class DefaultService :ServiceBase, IDefaultService
    {
        /// <summary>
        /// 添加实体
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="model"></param>
        /// <returns></returns>
        public virtual ActionResponse Add<TEntity>(TEntity model) where TEntity :TEntityBase, new()
        {
            return doAction(() =>
            {
                var db = new RepositoryBase<DataContext>();
                return db.Insert(model);
            });
        }

        public ActionResponse AddToList<TEntity>(List<TEntity> models, string tableName, string connectionStr, string primaryKey="Id", PrimaryKeyType type = PrimaryKeyType.ID) where TEntity : TEntityBase, new()
        {
            return doAction(() =>
            {
                var db = new RepositoryBase<DataContext>();
                return db.InsertToList(models,tableName,connectionStr,primaryKey);
            });
        }

        /// <summary>
        /// 更新实体
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="model"></param>
        /// <returns></returns>
        public virtual ActionResponse Update<TEntity>(TEntity model) where TEntity : TEntityBase, new()
        {
            return doAction(() =>
            {
                var db = new RepositoryBase<DataContext>();
                return db.Update(model);
            });
        }
        /// <summary>
        /// 批量更新实体
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="request"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public virtual ActionResponse UpdateToList<TEntity>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TEntity>> key) where TEntity: TEntityBase, new()
        {
            return doAction(() =>
            {
                var db = new RepositoryBase<DataContext>();
                return db.UpdateToList<TEntity>(predicate, key);
            });
        }
        /// <summary>
        /// 删除实体，支持批量删除
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="request"></param>
        /// <returns></returns>
        public virtual ActionResponse Remove<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : TEntityBase, new()
        {
            return doAction(() =>
            {
                var db = new RepositoryBase<DataContext>();
                return db.Remove<TEntity>(predicate);
            });
        }
        public virtual ItemResponse<TEntity> GetModel<TEntity>(Expression<Func<TEntity, bool>> predicate = null, Expression<Func<TEntity, TEntity>> selector = null) where TEntity : TEntityBase, new()
        {
            return GetModel(() =>
            {
                var db = new RepositoryBase<DataContext>();
                if (predicate == null && selector == null)
                {
                    return db.GetEntity<TEntity>();
                }
                else if (predicate == null && selector != null)
                {
                    return db.GetEntity<TEntity>(null, selector);
                }
                else if (predicate != null && selector == null)
                {
                    return db.GetEntity<TEntity>(predicate);
                }
                else if (predicate != null && selector != null)
                {
                    return db.GetEntity<TEntity>(predicate, selector);
                }
                return new TEntity();
            });
        }
        public virtual ItemResponse<TEntity> GetModel<TEntity>(object id) where TEntity : TEntityBase, new()
        {
            return GetModel(() =>
            {
                var db = new RepositoryBase<DataContext>();
                return db.GetEntity<TEntity>(id);
            });
        }
        public virtual ListResponse<TEntity> GetList<TEntity>(QueryRequest<TEntity> request=null, Expression<Func<TEntity, TEntity>> selector=null) where TEntity : TEntityBase, new()
        {
            return GetList<TEntity>(() =>
            {
                var db = new RepositoryBase<DataContext>();
                if (request == null && selector == null)
                {
                    return db.GetList<TEntity>();
                }
                else if (request == null && selector != null)
                {
                    return db.GetList<TEntity>(null,selector);
                }
                else if (request != null && selector == null)
                {
                    return db.GetList<TEntity>(request);
                }
                else if (request != null && selector != null)
                {
                    return db.GetList<TEntity>(request, selector);
                }
                return new  List<TEntity>();
            });
        }               
        /// <summary>
        /// 获取分页对象
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="request"></param>
        /// <returns></returns>
        public virtual PagingResponse<TEntity> Paging<TEntity>(PagingRequest<TEntity> request, Expression<Func<TEntity, TEntity>> selector = null) where TEntity : TEntityBase, new()
        {
            return GetPaging<TEntity>(() =>
            {
                var db = new RepositoryBase<DataContext>();
                int totalModels, totalPages;
                var list = db.GetPaging<TEntity>(request, out totalModels, out totalPages,selector);
                return new PagingList<TEntity>() { Models = list, TotalModels = totalModels, TotalPages = totalPages };
            });
        }
        /// <summary>
        /// 检查是否存在
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public virtual ActionResponse IsExist<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : TEntityBase, new()
        {
            return doAction(() =>
            {
                var db = new RepositoryBase<DataContext>();
                return db.CheckIsExist<TEntity>(predicate);
            });
        }
    }
}
